/*
 * @Author: fisher
 * @Date: 2024-02-06 11:51:44
 * @LastEditors: fisher luthor-li@qq.com
 * @LastEditTime: 2024-02-19 16:55:20
 * @FilePath: \allback\services\AuthService.js
 * @Description:
 */
// services/authService.js
const User = require('../models/User')
const bcrypt = require('bcryptjs')
const jwt = require('jsonwebtoken')
const secret = process.env.JWT_SECRET // 应由环境变量提供

/**
 * @description: 用户注册
 * @param {*} username
 * @param {*} email
 * @param {*} password
 * @return {*}
 */
exports.register = async (username, email, password) => {
  // 确保用户名和邮箱没有被占用
  const existingUser = await User.findOne({ $or: [{ username }, { email }] })
  if (existingUser) {
    throw new HttpError('用户名或邮箱已被注册!', 407)
  }
  // 对密码进行加密
  const salt = await bcrypt.genSalt(10)
  const hashedPassword = await bcrypt.hash(password, salt)
  // 创建新用户对象
  const user = new User({ username, email, password: hashedPassword })
  // 保存用户到数据库
  await user.save()
  return user
}

/**
 * @description: 用户登录
 * @param {*} username
 * @param {*} password
 * @return {*}
 */
exports.login = async (username, password) => {
  // 在数据库中查找用户
  const user = await User.findOne({ username: username })
  if (!user) {
    throw new HttpError('用户名不存在!', 408)
  }
  // 验证密码
  const isValid = await bcrypt.compare(password, user.password)
  if (!isValid) {
    throw new HttpError('密码错误!', 409)
  } else {
    // 身份验证成功后生成JWT
    const token = jwt.sign(
      { id: user._id }, // 你可以在 payload 中添加更多的用户信息
      secret,
      { expiresIn: '6h' } // token 的过期时间
    )
    return token
  }
}
exports.getToken = async (username, password) => {
  // 在数据库中查找用户
  const user = await User.findOne({ username: username })
  if (!user) {
    throw new HttpError('用户名不存在!', 408)
  }
  // 验证密码
  const isValid = await bcrypt.compare(password, user.password)
  if (!isValid) {
    throw new HttpError('密码错误!', 409)
  } else {
    // 身份验证成功后生成JWT
    const token = jwt.sign(
      { id: user._id }, // 你可以在 payload 中添加更多的用户信息
      secret,
      { expiresIn: '4w' } // token 的过期时间
    )
    return token
  }
}
/**
 * @description: 修改密码
 * @param {*} userId
 * @param {*} oldPassword
 * @param {*} newPassword
 * @return {*}
 */
exports.changeUserPassword = async (userId, oldPassword, newPassword) => {
  const user = await User.findById(userId)
  if (!user) {
    throw new HttpError('用户不存在!', 404)
  }
  const isMatch = await bcrypt.compare(oldPassword, user.password)
  if (!isMatch) {
    throw new HttpError('旧密码不正确!', 400)
  }
  const salt = await bcrypt.genSalt(10)
  const hashedNewPassword = await bcrypt.hash(newPassword, salt)
  await User.updateOne({ _id: userId }, { password: hashedNewPassword })
}
